﻿#include <QLabel>
#include <QMimeData>
#include <QDragEnterEvent>
#include <QDropEvent>
#include <QInputDialog>
#include <QMessageBox>
#include <QPushButton>
#include <QMenu>
#include <QCursor>
#include "UDropCellWidget.h"
#include "UChangeDevice.h"
#include "Global.h"
UDropCellWidget::UDropCellWidget(QWidget *parent)
	: QWidget(parent)
{
	ui.setupUi(this);
	m_pCurrGridItem = NULL;
	setAcceptDrops(true);  
	m_pGridLayout = new QGridLayout(this);
	m_pGridLayout->setSpacing(0);
	m_pGridLayout->setContentsMargins(0, 0, 0, 0);
	m_iRowCount = 4;
	m_iColCount = 4;
	m_vvUsedCells.resize(m_iRowCount);
	m_vecCellWidgets.resize(m_iRowCount);
	for (int i = 0; i < m_iRowCount; ++i) 
	{
		for (int j = 0; j < m_iColCount; ++j) 
		{
			m_vvUsedCells[i].push_back(false);
			QLabel *pCell = new QLabel(QString("(%1,%2)").arg(i).arg(j));
			pCell->setAlignment(Qt::AlignCenter);
			pCell->setStyleSheet("background-color: #FFFFFF; border: 1px solid #FFFFFF; color: #666;");
			pCell->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
			m_pGridLayout->addWidget(pCell, i, j);
			m_vecCellWidgets[i].push_back(pCell);
			
		}
		m_pGridLayout->setRowStretch(i, 1);
		m_pGridLayout->setColumnStretch(i, 1);
	}
}

UDropCellWidget::~UDropCellWidget()
{}

void UDropCellWidget::dragLeaveEvent(QDragLeaveEvent * event)
{
	Q_UNUSED(event);
	for (int i = 0; i < m_iRowCount; ++i) {
		for (int j = 0; j < m_iColCount; ++j) {
			m_vecCellWidgets[i][j]->setStyleSheet("background-color: #FFFFFF; border: 1px solid #999; color: #666;");
		}
	}
}

void UDropCellWidget::dragEnterEvent(QDragEnterEvent * event)
{
	if (event->mimeData()->hasFormat("guid"))
	{
		event->acceptProposedAction();
	}
		
}

void UDropCellWidget::dragMoveEvent(QDragMoveEvent * event)
{
	int rowSpan = QString::fromUtf8(event->mimeData()->data("row")).toInt();
	int colSpan = QString::fromUtf8(event->mimeData()->data("col")).toInt();
	QPoint pos = event->pos();
	QWidget *child = childAt(pos);

	int iRow = -1, iCol = -1;
	for (int i = 0; i < m_pGridLayout->rowCount(); ++i) {
		for (int j = 0; j < m_pGridLayout->columnCount(); ++j) {
			QLayoutItem *item = m_pGridLayout->itemAtPosition(i, j);
			if (item && item->widget() == child) {
				iRow = i;
				iCol = j;
				break;
			}
		}
	}

	for (int i = 0; i < m_iRowCount; ++i) {
		for (int j = 0; j < m_iColCount; ++j) {
			m_vecCellWidgets[i][j]->setStyleSheet("background-color: #fafafa; border: 1px solid #999; color: #666;");
		}
	}

	if (iRow != -1 && iCol != -1) {
		bool canPlace = true;
		if (iRow + rowSpan > m_iRowCount || iCol + colSpan > m_iColCount)
			canPlace = false;
		else {
			for (int i = iRow; i < iRow + rowSpan; ++i)
				for (int j = iCol; j < iCol + colSpan; ++j)
					if (m_vvUsedCells[i][j])
						canPlace = false;
		}

		for (int i = iRow; i < iRow + rowSpan && i < m_iRowCount; ++i) {
			for (int j = iCol; j < iCol + colSpan && j < m_iColCount; ++j) {
				QLabel* cell = m_vecCellWidgets[i][j];
				if (canPlace)
					cell->setStyleSheet("background-color: #c8facc; border: 1px solid #999;");  // 淡绿色
				else
					cell->setStyleSheet("background-color: red; border: 1px solid #999;");  // 红色冲突
			}
		}
	}

	event->acceptProposedAction();
}

void UDropCellWidget::dropEvent(QDropEvent *event)
{
	QPoint pos = event->pos();  
	QWidget *child = childAt(pos);
	int iRow = -1, iCol = -1;

	for (int i = 0; i < m_pGridLayout->rowCount(); ++i) 
	{
		for (int j = 0; j < m_pGridLayout->columnCount(); ++j) 
		{
			QLayoutItem *item = m_pGridLayout->itemAtPosition(i, j);
			if (item && item->widget() == child) 
			{
				iRow = i;
				iCol = j;
				break;
			}
		}
	}

	if (iRow == -1 || iCol == -1) return;
	int rowSpan = QString::fromUtf8(event->mimeData()->data("row")).toInt();
	int colSpan = QString::fromUtf8(event->mimeData()->data("col")).toInt();
	if (iRow + rowSpan > m_iRowCount || iCol + colSpan > m_iColCount) 
	{
		QMessageBox::warning(this, A2T("错误"), A2T("超出网格范围！"));
		return;
	}

	for (int i = iRow; i < iRow + rowSpan; ++i)
	{
		for (int j = iCol; j < iCol + colSpan; ++j)
		{
			if (m_vvUsedCells[i][j])
			{
				QMessageBox::warning(this, A2T("冲突"), A2T("目标区域已被占用！"));
				return;
			}
		}		
	}

	SDropInfo cDropInfo;
	cDropInfo.iCol = iCol;
	cDropInfo.iRow = iRow;
	cDropInfo.sGuid = QString::fromUtf8(event->mimeData()->data("guid"));
	cDropInfo.sCardGuid = QString::fromUtf8(event->mimeData()->data("cardguid"));;
	cDropInfo.sDllName = QString::fromUtf8(event->mimeData()->data("dllname"));;
	cDropInfo.nDeviceType = QString::fromUtf8(event->mimeData()->data("devicetype")).toInt();;
	cDropInfo.nIndex = QString::fromUtf8(event->mimeData()->data("index")).toInt();
	cDropInfo.rowSpan = rowSpan;
	cDropInfo.colSpan = colSpan;
	if (cDropInfo.sGuid == "")
	{
		bindDevice(cDropInfo);
	}
	else
	{
		addDropWidget(cDropInfo);
		event->acceptProposedAction();
	}
}

void UDropCellWidget::setGridItems(QVector<SPageItem> vecPageItem)
{
	for (int i = 0; i < m_vGridItem.size(); i++)
	{
		removeItem(m_vGridItem[i]);
		delete m_vGridItem[i]->pViewWidget; // 释放控件内存
		delete m_vGridItem[i]; // 释放GridItem内存
	}
	m_vGridItem.clear();
	for (int i = 0; i < vecPageItem.size(); i++)
	{
		int nIndex = vecPageItem[i].nRow * 4 + vecPageItem[i].nCol;
		CDragPreviewWidget *pViewWidget = getCardWidget(vecPageItem[i].sGuid, vecPageItem[i].sCardGuid, nIndex);
		if (pViewWidget != nullptr)
		{
			GridItem* pGridItem = new GridItem(pViewWidget->m_sDllName, pViewWidget->m_nDeviceType, vecPageItem[i].sGuid, vecPageItem[i].sCardGuid, vecPageItem[i].nRow, vecPageItem[i].nCol, pViewWidget, vecPageItem[i].nRowSpan, vecPageItem[i].nColSpan);
			addItem(pGridItem);
		}
	}
}


QVector<SPageItem> UDropCellWidget::getGridItems()
{
	QVector<SPageItem> vecPageItem;
	for (int i = 0; i < m_vGridItem.size(); i++)
	{
		SPageItem sPageItem(m_vGridItem[i]->sGuid, m_vGridItem[i]->sCardGuid,m_vGridItem[i]->nRow, m_vGridItem[i]->nCol, m_vGridItem[i]->nRowSpan, m_vGridItem[i]->nColSpan);
		vecPageItem.push_back(sPageItem);
	}
	return vecPageItem;
}

void UDropCellWidget::addDropWidget(SDropInfo cDropInfo)
{
	CDragPreviewWidget *pViewWidge = nullptr;
	for (int i = 0; i < m_vGridItem.size(); ++i)
	{
		int nOldIndex = m_vGridItem[i]->nRow * 4 + m_vGridItem[i]->nCol;
		if (m_vGridItem[i]->sCardGuid == cDropInfo.sCardGuid && m_vGridItem[i]->sGuid == cDropInfo.sGuid && nOldIndex == cDropInfo.nIndex)
		{
			pViewWidge = m_vGridItem[i]->pViewWidget;
			removeItem(m_vGridItem[i]);
			m_vGridItem.removeAt(i);
			break;
		}
	}
	if (!pViewWidge)
	{
		pViewWidge = getCardWidget(cDropInfo.sDllName, cDropInfo.nDeviceType, cDropInfo.sCardGuid, cDropInfo.iRow * 4 + cDropInfo.iCol, cDropInfo.sGuid);
	}
	else
	{
		pViewWidge->setIndex(cDropInfo.iRow * 4 + cDropInfo.iCol);
	}
	GridItem* pGridItem = new GridItem(pViewWidge->m_sDllName, pViewWidge->m_nDeviceType, cDropInfo.sGuid, cDropInfo.sCardGuid, cDropInfo.iRow, cDropInfo.iCol, pViewWidge, cDropInfo.rowSpan, cDropInfo.colSpan);
	addItem(pGridItem);
}

void UDropCellWidget::bindDevice(SDropInfo cDropInfo)
{
	m_cDropInfo = cDropInfo;
	UChangeDevice *pChangeDevice = new UChangeDevice(cDropInfo.sDllName, cDropInfo.sGuid,true, cDropInfo.nDeviceType);
	connect(pChangeDevice, &UChangeDevice::sign_addDevice, this, &UDropCellWidget::slot_addCardDevice);
	pChangeDevice->show();
}


void UDropCellWidget::addItem(GridItem * pGridItem)
{
	m_pGridLayout->addWidget(pGridItem->pViewWidget, pGridItem->nRow, pGridItem->nCol, pGridItem->nRowSpan, pGridItem->nColSpan);
	for (int i = pGridItem->nRow; i < pGridItem->nRow + pGridItem->nRowSpan; ++i)
	{
		for (int j = pGridItem->nCol; j < pGridItem->nCol + pGridItem->nColSpan; ++j)
		{
			m_vvUsedCells[i][j] = true;
		}
	}
	m_vGridItem.push_back(pGridItem);
}

void UDropCellWidget::removeItem(const GridItem * pGridItem)
{
	m_pGridLayout->removeWidget(pGridItem->pViewWidget);
	updateUsedCells(pGridItem->nRow, pGridItem->nCol, pGridItem->nRowSpan, pGridItem->nColSpan, false);
}

void UDropCellWidget::updateUsedCells(int row, int col, int rowSpan, int colSpan, bool used)
{
	for (int i = row; i < row + rowSpan; ++i)
	{
		for (int j = col; j < col + colSpan; ++j)
		{
			m_vvUsedCells[i][j] = used;
		}
	}		
}

void UDropCellWidget::setupContextMenu(QWidget * pWidget)
{
	connect(pWidget, &QWidget::customContextMenuRequested, this, [=](const QPoint &) {
		QMenu menu;
		QAction *changeDevice = menu.addAction(A2T("修改绑定设备"));
		QAction *del = menu.addAction(A2T("删除控件"));
		QAction *selected = menu.exec(QCursor::pos());
		if (selected == changeDevice)
		{
			for (int i = 0; i < m_vGridItem.size(); ++i)
			{
				if (m_vGridItem[i]->pViewWidget == pWidget)
				{
					m_pCurrGridItem = m_vGridItem[i];
					QString sDllName = m_vGridItem[i]->sDllName;
					int nDeviceType = m_vGridItem[i]->nDeviceType;					
					UChangeDevice *pChangeDevice = new UChangeDevice(sDllName, m_vGridItem[i]->sGuid, nDeviceType);
					pChangeDevice->show();
					connect(pChangeDevice, &UChangeDevice::sign_selectDevice, this, &UDropCellWidget::slot_changeCardDevice);
					break;
				}
			}
			
		}
		if (selected == del) 
		{
			bool bSure = showMessageBox(this, A2T("提示"), A2T("确认删除此节点或者界面吗？"), 1, true);
			if (bSure)
			{
				for (int i = 0; i < m_vGridItem.size(); ++i)
				{
					if (m_vGridItem[i]->pViewWidget == pWidget)
					{
						removeItem(m_vGridItem[i]);
						m_vGridItem.removeAt(i);
						delete pWidget;
						break;
					}
				}
			}
			
		}
	});
}

CDragPreviewWidget * UDropCellWidget::getCardWidget(QString sGuid, QString sCardGuid, int nIndex)
{
	CDragPreviewWidget *pViewWidge = nullptr;
	CBaseNode *pNode = g_pRoot->findNodeById(sGuid);
	if (pNode != nullptr)
	{
		CBaseDevice *pDevice = (CBaseDevice *)pNode;
		QWidget *pWidget = g_mapCardWidget[pDevice->getDllName()][pDevice->getDeviceType()].vecWidget[sCardGuid.toInt()];
		pViewWidge = new CDragPreviewWidget(sGuid, sCardGuid, pDevice->getDllName(), pDevice->getDeviceType(), pWidget, nIndex, this);
		setupContextMenu(pViewWidge);
	}
	return pViewWidge;
}

CDragPreviewWidget * UDropCellWidget::getCardWidget(QString sDllName, int nDeviceType, QString sCardGuid,int nIndex, QString sGuid)
{
	CDragPreviewWidget *pViewWidge = nullptr;
	QWidget *pWidget = g_mapCardWidget[sDllName][nDeviceType].vecWidget[sCardGuid.toInt()];
	pViewWidge = new CDragPreviewWidget(sGuid, sCardGuid, sDllName, nDeviceType, pWidget, nIndex, this);
	setupContextMenu(pViewWidge);
	return pViewWidge;
}

void UDropCellWidget::slot_addCardDevice(QString sGuid)
{
	if (sGuid != "")
	{
		m_cDropInfo.sGuid = sGuid;
		addDropWidget(m_cDropInfo);
	}	
}

void UDropCellWidget::slot_changeCardDevice(QString sGuid)
{
	if (m_pCurrGridItem != NULL)
	{
		m_pCurrGridItem->sGuid = sGuid;
		m_pCurrGridItem->pViewWidget->setGuid(sGuid);
	}
}
